package com.dynamo.transport.network.practise.bootstrap;

import com.dynamo.transport.network.practise.channel.*;
import com.dynamo.transport.network.practise.channel.socket.nio.NioChannelSink;
import com.dynamo.transport.network.practise.channel.socket.nio.NioClientSocketChannel;
import com.dynamo.transport.network.practise.channel.socket.nio.NioWorker;
import com.dynamo.transport.network.practise.channel.socket.nio.NioWorkerPool;

import java.net.SocketAddress;
import java.util.concurrent.Executor;

/**
 * @author duanyimiao
 * @create 2018-12-18 5:32 PM
 * @description 将ChannelPipeline NioWorker NioBoss这些类关联起来
 **/
public class ClientBootstrap extends Bootstrap {

    private Executor worker;
    private NioWorkerPool workerPool;
    private NioClientSocketChannel socketChannel;

    //TODO 如何使用ChannelFactory来创建Channel
    public ClientBootstrap(Executor worker, Class<? extends Channel> channel, SocketAddress remoteSocketAddress, ChannelPipelineFactory pipelineFactory) {
        try {
            this.worker = worker;
            workerPool = new NioWorkerPool(worker, 1);
            ChannelPipeline pipeline = pipelineFactory.getPipeline();
            pipeline.addLast("connect", new Connecter());

            this.socketChannel = new NioClientSocketChannel(pipeline, remoteSocketAddress);

            //当连接成功了再去监听 监听客户端的连接
            System.out.println("register client channel to selector socketChannel" + socketChannel);
            ((NioWorker) workerPool.nextWorker()).register(socketChannel, null);

            //向Downstream connect事件
            //门面模式，当需要更换ChannelPipeline实现时只需要更改其门面类Channels即可
            Channels.connect(pipeline, socketChannel);

            while(!socketChannel.channel.finishConnect()){
                System.out.println("not connect to server");
            }

            Channels.write(pipeline, socketChannel, "nihaoma ");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void start(SocketAddress localSocketAddress) {


    }

    private class Connecter extends SimpleChannelUpstreamHandler {

        @Override
        public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) {
            System.out.println("client channel has been create");
            //TODO 通过ChannelConfig配置Channel

            //TODO 明显直接写死的NioChannelSink，这里如何满足开闭原则
            e.getPipelien().attach(e.getChannel(), new NioChannelSink());

        }

    }


}
